package com.soul.common.service.impl;

import com.soul.common.bean.vo.BaseDataVo;
import com.soul.common.bean.vo.DictionaryVo;
import com.soul.common.bean.vo.FileVo;
import com.soul.common.bean.vo.UserVo;
import com.soul.common.enums.BizCacheKeyEnum;
import com.soul.common.feign.CommDictService;
import com.soul.common.fun.BaseDataFunc;
import com.soul.common.service.BaseDataService;
import com.soul.common.service.CacheService;
import com.soul.common.utils.FormatUtil;
import com.soul.common.utils.ListUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import java.util.*;

/**
 * @author Shiws
 * @version 1.0
 * @date 2023/11/21 9:44
 */
@Service
public class BaseDataServiceImpl implements BaseDataService {

    @Autowired
    private CacheService cacheService;
    @Autowired(required = false)
    private CommDictService dictService;

    @Override
    public <T> BaseDataVo loadBaseData(List<T> list, BaseDataFunc<T> func) {
        BaseDataVo baseDataVo = new BaseDataVo();
        this.loadBaseData(list, func, baseDataVo);
        return baseDataVo;
    }
    @Override
    public <T> void loadBaseData(List<T> list, BaseDataFunc<T> func, BaseDataVo baseDataVo) {
        this.setBaseData(list,func,baseDataVo);
        this.loadBaseData(baseDataVo);
    }

    public Map<Long, UserVo> getUserVoMap(List<Long> userIds){
        return ListUtil.listToMap(this.getUserVos(userIds), UserVo::getId);
    }
    public List<UserVo> getUserVos(List<Long> userIds){
        if(!ObjectUtils.isEmpty(userIds)){
            Map<String,Set<String>> keyMap = new HashMap<>();
            Set<String> keys = ListUtil.toValueSet(userIds, FormatUtil::toString);
            keyMap.put(BizCacheKeyEnum.USER.getCode(),keys);
            List<UserVo> userVos = cacheService.getGlobalObjectList(UserVo.class, keyMap);
            return userVos;
        }
        return null;
    }

    public Map<Long, FileVo> getFileVoMap(List<Long> fileIds){
        return ListUtil.listToMap(this.getFileVos(fileIds), FileVo::getId);
    }
    public List<FileVo> getFileVos(List<Long> fileIds){
        if(!ObjectUtils.isEmpty(fileIds)){
            Map<String,Set<String>> keyMap = new HashMap<>();
            Set<String> keys = ListUtil.toValueSet(fileIds, FormatUtil::toString);
            keyMap.put(BizCacheKeyEnum.FILE.getCode(),keys);
            List<FileVo> fileVos = cacheService.getGlobalObjectList(FileVo.class, keyMap);
            return fileVos;
        }
        return null;
    }
    @Override
    public void loadBaseData(BaseDataVo baseDataVo) {
        if(!ObjectUtils.isEmpty(baseDataVo.getUserIds())){
            Set<Long> userIds = baseDataVo.getUserIds();
            baseDataVo.getUserVoMap().putAll(this.getUserVoMap(new ArrayList<>(userIds)));
        }
        if(!ObjectUtils.isEmpty(baseDataVo.getFileIds())){
            Set<Long> fileIds = baseDataVo.getFileIds();
            baseDataVo.getFileVoMap().putAll(this.getFileVoMap(new ArrayList<>(fileIds)));
        }
        if(!ObjectUtils.isEmpty(baseDataVo.getDictTypes())){
            List<String> dictTypes = new ArrayList<String>(baseDataVo.getDictTypes());
            List<DictionaryVo> dictionaryVos = dictService.queryDictListByTypes(dictTypes);
            Map<String, Map<String, DictionaryVo>> dictMap = ListUtil.listToMapListMap(dictionaryVos, DictionaryVo::getType, DictionaryVo::getId);
            baseDataVo.getDictVoMap().putAll(dictMap);
        }
    }
    @Override
    public <T> void setBaseData(List<T> list , BaseDataFunc<T> func, BaseDataVo baseDataVo){
        if(!ObjectUtils.isEmpty(list)){
            for(T t : list){
                func.setVo(t,baseDataVo);
            }
        }
    }

}
